package com.sanben.common.exception;


import com.sanben.common.enums.ErrorMessage;
import com.sanben.common.web.domain.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;


/**
 * @author: cyh
 * @description:全局异常处理类
 * @date: 2020/8/03 10:57
 */
@RestControllerAdvice
@Slf4j
public class ControllerExceptionHandler {

    /**
     * 服务异常
     */
    @ExceptionHandler(ServiceException.class)
    @ResponseBody
    public Result serviceException(ServiceException e) {
        log.error(e.getMessage(), e);
        return Result.ServiceError(e.getCode(), e.getMessage());
    }

    /**
     * 处理Get请求中(也就是表单) 使用@Valid 验证路径中请求实体校验失败后抛出的异常，详情继续往下看代码
     *
     * @param e
     * @return
     */
    @ExceptionHandler(BindException.class)
    @ResponseBody
    private Result BindException(BindException e) {
        String msg = e.getFieldError().getDefaultMessage();
        log.error(msg, e);
        return Result.ServiceError(msg);
    }

    /**
     * 处理请求参数格式错误 @RequestBody上validate失败后抛出的异常是MethodArgumentNotValidException异常。
     *
     * @param e
     * @return
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    private Result MethodArgumentNotValidException(MethodArgumentNotValidException e) {
        String msg = e.getBindingResult().getFieldError().getDefaultMessage();
        log.error(msg, e);
        return Result.ServiceError(msg);
    }

    /**
     * @RequestParam 缺少参数异常
     *
     * @param ex
     * @return
     */
    @ExceptionHandler({MissingServletRequestParameterException.class})
    @ResponseBody
    public Result requestMissingServletRequest(MissingServletRequestParameterException ex) {
        log.error(ex.getMessage(), ex);
        return Result.ServiceError(-400, "缺少必要参数,参数名称为" + ex.getParameterName());
    }

    /**
     * 系统异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(Exception.class)
    @ResponseBody
    private Result runtimeExceptionHandler(Exception e) {
        ErrorMessage errorMessage = ErrorMessage.SYS_ERROR;
        log.error(e.getMessage(), e);
        return Result.ServiceError(errorMessage.getCode(), errorMessage.getMessage());
    }
}
